//package ay.shadow.shadowcommongateway.filter;
//
//import ay.shadow.shadowcommongateway.nacos.AvailableService;
//import jakarta.annotation.Resource;
//import org.springframework.boot.autoconfigure.AutoConfigureBefore;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
//import org.springframework.cloud.client.ServiceInstance;
//import org.springframework.cloud.client.loadbalancer.DefaultResponse;
//import org.springframework.cloud.client.loadbalancer.LoadBalancerUriTools;
//import org.springframework.cloud.client.loadbalancer.Response;
//import org.springframework.cloud.gateway.config.GatewayLoadBalancerProperties;
//import org.springframework.cloud.gateway.config.GatewayReactiveLoadBalancerClientAutoConfiguration;
//import org.springframework.cloud.gateway.filter.GatewayFilterChain;
//import org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter;
//import org.springframework.cloud.gateway.support.DelegatingServiceInstance;
//import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.stereotype.Component;
//import org.springframework.web.server.ServerWebExchange;
//import reactor.core.publisher.Mono;
//
//import java.net.URI;
//
///**
// * @author shadow
// */
//@Configuration
//@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
//public class ShadowServerFilter extends ReactiveLoadBalancerClientFilter {
//
//    private  AvailableService availableService;
//
//    public ShadowServerFilter(GatewayLoadBalancerProperties properties) {
//        super(null, properties);
//    }
//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        URI url = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
//        String schemePrefix = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
//        if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
//            return chain.filter(exchange);
//        }
//        // preserve the original url
//        ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
//
////        if (log.isTraceEnabled()) {
////            log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url);
////        }
//
//        return choose(exchange).doOnNext(response -> {
//
////            if (!response.hasServer()) {
////                throw NotFoundException.create(loadBalancerProperties.isUse404(),
////                        "Unable to find instance for " + url.getHost());
////            }
//
//            URI uri = exchange.getRequest().getURI();
//
//            // if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,
//            // if the loadbalancer doesn't provide one.
//            String overrideScheme = null;
//            if (schemePrefix != null) {
//                overrideScheme = url.getScheme();
//            }
//
//            DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(response.getServer(),
//                    overrideScheme);
//
//            URI requestUrl = LoadBalancerUriTools.reconstructURI(serviceInstance, uri);
//
////            if (log.isTraceEnabled()) {
////                log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
////            }
//            exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
//        }).then(chain.filter(exchange));
//    }
//
//    private Mono<Response<ServiceInstance>> choose(ServerWebExchange exchange) {
//        URI uri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
//        ServiceInstance serviceInstance = availableService.available(uri.getHost(), exchange.getRequest());
//        return Mono.just(new DefaultResponse(serviceInstance));
//    }
//}
